local oo = require("SharedLibs.BaseLib");

local CoUtils = require("SharedLibs.CoUtils");
Debugger = require("SharedLibs.Debugger");
AsyncOp = require("SharedLibs.AsyncOp");
AsyncOpState = require("SharedLibs.AsyncOpState");

Seq = require("SharedLibs.FP.Sequence");

---
local CombinedOp = oo.Class()
CombinedOp.name = "CombinedOp"
oo.ClassExtends(CombinedOp, AsyncOp)

function CombinedOp.prototype.constructor(self, ...)
	CombinedOp._ss.prototype.constructor(self)

	self._opList = {};
	self._onStopped = nil;
	self._onComplete = nil;

	local args = {...};
	--- 不能直接用ipairs, 因为输入的参数里可能包含nil
	local count = select("#", ...);

	for i=1, count do
		local val = args[i];
		local op = CoUtils.ToOp(val);
		Debugger.Assert(op.state == AsyncOpState.Ready);
		table.insert(self._opList, op);
	end
end

oo.SetDescriptor(
	CombinedOp.prototype,
	"isCombinedOp",
	{
		get = function(self)
			return true;
		end
	},
	true 
)

function CombinedOp.prototype.OnStopped(self, onStopped) 
	self._onStopped = onStopped; 
	return self; 
end

function CombinedOp.prototype.GetOnStopped(self)
	return self._onStopped;
end

function CombinedOp.prototype.OnComplete(self, onComplete) 
	self._onComplete = onComplete; 
	return self; 
end

function CombinedOp.prototype.GetChildren(self)
	return Seq.fromArray(self._opList);
end

function CombinedOp.prototype.Get(self, index)
	assert(index >= 0 and index <= #self._opList);
	return self._opList[index];
end

--- 返回op在opList里的索引. 
function CombinedOp.prototype.GetIndex(self, op)
	for i, op_ in ipairs(self._opList) do
		if op_ == op then
			return i;
		end 
	end
	assert(false);
end

function CombinedOp.prototype.Add(self, op)
	assert(self._state == AsyncOpState.Ready);
	if nil == op then return end;

	local op = CoUtils.ToOp(op);

	assert(op.state == AsyncOpState.Ready);

	if Debugger.developMode then
		for i,v in ipairs(self._opList) 
		do assert(v ~= op)
		end		
	end	

	table.insert(self._opList, op);
end

function CombinedOp.prototype:_onStop(isComplete)
	for i,op in ipairs(self._opList) do 
		op:Stop()
	end		
	
	if self._onStopped ~= nil then self:_onStopped(); end
	if self._onComplete ~= nil then self:_onComplete(); end
end

function CombinedOp.prototype._isChildOp(self, asyncOp)
	for i,op in ipairs(self._opList) do 
		if op == asyncOp then 
			return true 
		end
	end
	return false;
end

function CombinedOp.prototype:_resetOps(asyncOp)
	for i, op in ipairs(self._opList) do 
		op:Reset()
	end			
end

return CombinedOp;